package com.gitee.feizns.upload.service.impl;

import com.gitee.feizns.upload.domain.enums.ResourceType;
import com.gitee.feizns.upload.domain.pojo.Resource;
import com.gitee.feizns.upload.domain.prop.UploadConfigProperties;
import com.gitee.feizns.upload.domain.vo.ResourceVo;
import com.gitee.feizns.upload.service.UploadService;
import com.gitee.feizns.web.ex.HttpException;
import com.gitee.feizns.web.utils.FileUtils;
import com.gitee.feizns.web.utils.WebUtils;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

/**
 * @author feizns
 * @since 2019/8/9
 */
@Service
@EnableConfigurationProperties(UploadConfigProperties.class)
public class UploadServiceImpl implements UploadService {

    @Autowired
    private UploadConfigProperties config;

    @Override
    public ResourceVo upload(InputStream stream, String originalFilename, ResourceType type) {
        Resource resource = create(originalFilename, type);
        resource.insert();
        try {
            write(stream, resource.getFilename(), type);
        } catch (IOException e) {
            throw new HttpException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
        }
        return resource.to(ResourceVo.class);
    }

    @Override
    public String swapAbsoluteUrl(String filename) {
        return getWebAbsolute(filename);
    }

    private Resource create(String originalFilename, ResourceType type) {
        Resource ret = new Resource();
        ret.setType(type);
        ret.setFromIp(WebUtils.getIpAddress());
        ret.setFilename(UploadService.generatorFilename(originalFilename));
        ret.setAbUrl(getWebAbsolute(ret.getFilename()));
        return ret;
    }

    private String getWebAbsolute(String filename) {
        String prefix = config.getAbsolutePrefix();
        return (prefix == null ? WebUtils.getBasePath() + "/" : prefix) + filename;
    }

    private void write(InputStream stream, String newFilename, ResourceType type) throws IOException {
        String[] dirs = config.getUploadDirs();
        if ( dirs != null ) {
            File[] files = Arrays.stream(dirs).map(item -> new File(item, newFilename)).toArray(File[]::new);
            FileUtils.writer(stream, files);
            handleFiles(type, files);
        }
    }

    private void handleFiles(ResourceType type, File... files) throws IOException {
        if ( type == ResourceType.IMAGE ) {
            for (File file : files) {
                if ( file.length() > config.getMinQualitySize() ) {
                    Thumbnails.Builder<File> builder = Thumbnails.of(file).scale(config.getScale()).outputQuality(config.getQuality());

                    //写入水印，（如果需要）
                    if ( config.getMarkFile() != null ) {
                        try ( InputStream is =  new FileInputStream(config.getMarkFile()) ) {
                            BufferedImage image = Thumbnails.of(is).asBufferedImage();
                            builder = builder.watermark(config.getMarkPosition(), image, config.getMarkTransparent());
                        }
                    }

                    builder.toFile(file);
                }
            }
        }
    }

}
